package dao

import (
	"context"
	"device-admin/internal/dal"
	"device-admin/internal/models"

	"192.168.1.75/go-pkg/errorx"
)

// 本地词库
type LocalQALib struct{}

// Add 新增词库
func (LocalQALib) Add(ctx context.Context, query *dal.Query, name, merchantID string) (string, error) {
	if name == "" {
		return "", errorx.New("词库名称不能为空", -1)
	}
	if merchantID == "" {
		return "", errorx.New("商户id不能为空", -1)
	}
	l := dal.LocalQALib
	// 直系商户下，词库不能重复
	if merchantID != "1" {
		count, err := l.WithContext(ctx).
			Where(l.Name.Eq(name)).
			Where(l.MerchantID.In(GetFamilyMerchants(merchantID)...)).
			Count()
		if err != nil || count > 0 {
			return "", errorx.New("词库名称不能重复", -1)
		}
	} else {
		count, err := l.WithContext(ctx).
			Where(l.Name.Eq(name)).
			Where(l.MerchantID.Eq(merchantID)).
			Count()
		if err != nil || count > 0 {
			return "", errorx.New("词库名称不能重复", -1)
		}
	}
	// 新增词库
	record := models.LocalQALib{}
	record.Name = name
	record.MerchantID = merchantID
	err := l.WithContext(ctx).Create(&record)
	if err != nil {
		return "", errorx.New("新增词库失败", -1)
	}
	return record.ID, nil
}

// Update 更新词库
func (LocalQALib) Update(ctx context.Context, query *dal.Query, id, name, merchantID string, totalAnswer int64) error {
	if id == "" {
		return errorx.New("词库id不能为空", -1)
	}
	l := dal.LocalQALib
	lx := l.WithContext(ctx)
	// 只能更新直系商户的词库
	if merchantID != "1" {
		lx = lx.Where(l.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	// 词库id
	lx = lx.Where(l.ID.Eq(id))
	// 待更新的记录
	record := map[string]interface{}{}
	if name != "" {
		record[l.Name.ColumnName().String()] = name
	}
	if totalAnswer >= 0 {
		record[l.TotalAnswer.ColumnName().String()] = totalAnswer
	}
	// 更新词库名称
	res, err := lx.Updates(record)
	if err != nil || res.RowsAffected <= 0 {
		return errorx.New("词库更新失败", -1)
	}
	return nil
}

// Delete 删除词库
func (LocalQALib) Delete(ctx context.Context, query *dal.Query, id, merchantID string) error {
	if id == "" {
		return errorx.New("词库id不能为空", -1)
	}
	if merchantID == "" {
		return errorx.New("商户id不能为空", -1)
	}
	l := query.LocalQALib
	lx := l.WithContext(ctx)
	// 直系商户
	if merchantID != "1" {
		lx.Where(l.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	// 词库id
	lx = lx.Where(l.ID.Eq(id))
	// 删除
	res, err := lx.Delete(&models.LocalQALib{})
	if err != nil || res.RowsAffected <= 0 {
		return errorx.New("词库删除失败", -1)
	}
	return nil
}

// List 词库列表
func (LocalQALib) List(
	ctx context.Context,
	query *dal.Query,
	name, merchantID string,
	page, limit int,
) (list []*models.LocalQALib, total int64, err error) {
	if merchantID == "" {
		return []*models.LocalQALib{}, 0, errorx.New("商户id不能为空", -1)
	}
	l := dal.LocalQALib
	lx := l.WithContext(ctx)
	// 词库名称
	if name != "" {
		lx = lx.Where(l.Name.Like("%" + name + "%"))
	}
	// 所属商户
	if merchantID != "1" {
		lx = lx.Where(l.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	// 记录条数
	total, err = lx.Count()
	if err != nil {
		return []*models.LocalQALib{}, 0, nil
	}
	// 获取分页记录
	list, err = lx.
		Offset(GetPageOffset(page, limit)).
		Limit(GetPageLimit(limit)).
		Find()
	if err != nil {
		return []*models.LocalQALib{}, 0, nil
	}
	return list, total, nil
}

type LocalQALibDetailType struct {
	models.LocalQALib
	RobotID []string `json:"robot_id" gorm:"-"`
}

// Detail 词库详情
func (LocalQALib) Detail(
	ctx context.Context,
	query *dal.Query,
	libID string,
	merchantID string,
) (*LocalQALibDetailType, error) {
	l := query.LocalQALib
	tx := l.WithContext(ctx).Where(l.ID.Eq(libID))
	if merchantID == "1" {
		tx = tx.Where(l.MerchantID.Eq("1"))
	} else {
		tx = tx.Where(l.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	var detail = &LocalQALibDetailType{}
	err := tx.Scan(detail)
	return detail, err
}

// Exists 词库是否存在
func (LocalQALib) Exists(ctx context.Context, query *dal.Query, libID string) bool {
	l := query.LocalQALib
	tx := l.WithContext(ctx).Where(l.ID.Eq(libID))
	count, _ := tx.Count()
	return count == 1
}

// 答案
type LocalQAAnswer struct{}

// Add 新增答案
func (LocalQAAnswer) Add(ctx context.Context, query *dal.Query, records []*models.LocalQAAnswer, batchSize int) error {
	l := query.LocalQAAnswer
	err := l.WithContext(ctx).CreateInBatches(records, batchSize)
	return err
}

// Delete 删除词库的答案
func (LocalQAAnswer) BatchDelete(ctx context.Context, query *dal.Query, libID string) (int64, error) {
	l := query.LocalQAAnswer
	res, err := l.WithContext(ctx).Where(l.LibID.Eq(libID)).Delete(&models.LocalQAAnswer{})
	return res.RowsAffected, err
}

// Detail 词库答案详情
func (LocalQAAnswer) Detail(ctx context.Context, query *dal.Query, answerID string) (*models.LocalQAAnswer, error) {
	l := query.LocalQAAnswer
	return l.WithContext(ctx).Where(l.ID.Eq(answerID)).Take()
}

// 关键词
type LocalQAKeyword struct{}

// Add 新增关键词
func (LocalQAKeyword) Add(ctx context.Context, query *dal.Query, records []*models.LocalQAKeyword, batchSize int) error {
	l := query.LocalQAKeyword
	err := l.WithContext(ctx).CreateInBatches(records, batchSize)
	return err
}

// Delete 删除词库关键字
func (LocalQAKeyword) BatchDelete(ctx context.Context, query *dal.Query, libID string) (int64, error) {
	l := query.LocalQAKeyword
	res, err := l.WithContext(ctx).Where(l.LibID.Eq(libID)).Delete(&models.LocalQAKeyword{})
	return res.RowsAffected, err
}

// List 关键字记录列表
func (LocalQAKeyword) List(
	ctx context.Context,
	query *dal.Query,
	libID, keyword string,
) ([]*models.LocalQAKeyword, error) {
	l := query.LocalQAKeyword
	return l.WithContext(ctx).
		Where(l.LibID.Eq(libID)).
		Where(l.Keyword.Eq(keyword)).
		Find()
}
